<?
/////////////////////////////////////////////////////////////////////////////////////////
// Clase para Manejar Bases SQL Server
/////////////////////////////////////////////////////////////////////////////////////////
class DatabaseSQL 
	{
		// Propiedades de la Conexion
		var $cServer = "";
		var $cDatabase = "";
		var $cUser = "";
		var $cPassword = "";
		var $nConnection = 0;
		var $cSql;
		var $bEof;
	
		// Propiedades para el manejo de resultsets
		var $nQuery = 0;
		var $aFields= array();

		function beginTran()
		{
			return $this->execute( "BEGIN TRAN" );
		}
		function commitTran()
		{
			return $this->execute( "COMMIT TRAN" );
		}
		function rollBackTran()
		{
			return $this->execute( "ROLLBACK TRAN" );
		}

		function dbLower( $cString ) 
		{
			return " lower($cString) ";
		}
		
		function dbNumToStr( $cString ) 
		{
			return " cast($cString as varchar) ";
		}
	
		function dbDateToStr( $cString , $cFormato ) 
		{
			$nFormato = $cFormato == "yyyy-mm-dd" ? 111: 103;
			return " convert( varchar, $cString, $nFormato ) ";
		}
		
		function dbValue ( $cValor ) 
		{
			$cValor = trim($cValor);			
			if ( $cValor === "")  
			{
				$cValor = "null";
			} else 
			{
				if ( ! (strpos( $cValor, "'" )  === FALSE) ) 
				{
					$cValor = str_replace( "'", "''", $cValor);
				}
				$cValor = "'$cValor'";
			}			
			return $cValor;
		}
		
		// Devuelve el numero total de Registros del Query, independientemente de que se haya puesto un TOP
		function totalFilas( $cSql, $cPatron = "FROM") {
			$cSql = strtoupper( $cSql);
			$cPatron = strtoupper($cPatron);
			$nPos = strpos($cSql, $cPatron );	
	
			$cSql = "SELECT COUNT(*) " . substr( $cSql , $nPos );
	
				// Si Tiene Group by => Este es un Truco para obtener la cantidad de Registros
				if ( strpos($cSql, "GROUP BY" ) > 0  ) {
	//    		$cSql = "SELECT COUNT(*) FROM ( $cSql ) as Tabla";
					$cSql = "SELECT COUNT(*) FROM (" . str_replace("COUNT(*)", "COUNT(*) AS NREG", $cSql) .")";
					$cSql = "$cSql  as Tabla";
				}
			$nqRows = $this->getData($cSql);
	
			return $nqRows;
		}
	
		function DatabaseSQL($cServer, $cDatabase, $cUser = "", $cPassword = ""){
			$this->cServer = $cServer;
			$this->cDatabase = $cDatabase;
			$this->cUser = $cUser;
			$this->cPassword = $cPassword;
			$this->nConnection = 0;
			$this->bEof = true;
		}
		
		function saveQuery( $cArchivo , $cDelimitadorCampo = "'", $cSeparadorCampo = "," ) 
		{
			// Si No hay un Query da Error
			if ( $this->nQuery )
			{
				return false;	
			}
			
			$fd = fopen($cArchivo , "w");
			while ( $this->moveNext() ) 
			{
				fwrite($fd, $this->getFields( $cDelimitadorCampo, $cSeparadorCampo ) );
			}
			fclose($fd);
		}
	
		function getHeaders( $cDelimitadorCampo = "'", $cSeparadorCampo = "," , $cSeparadorRegistros = "\n" ) 
		{
			// Si No hay un Query da Error
			if ( $this->nQuery )
			{
				return false;	
			}
			// Se mueve al Primer Registro y arma una cadena con los nombres de los campos separados por el delimitador
			$this->moveTo(0);	
			$aKeys 	  = array_keys( $this->aFields  );
			$nqCampos = count($aKeys);
			for( $nCampo = 1; $nCampo < $nqCampos; $nCampo +=2 ) 
			{
				$cData .=  $cDelimitadorCampo . $aKeys[$nCampo] . $cDelimitadorCampo . $cSeparadorCampo;
			}			
			if ( $cData  != "" ) 
			{
				$cData =  substr( $cData , 0, strlen($cData) - strlen($cSeparadorCampo) );
			}
			// Devuelve la cadena
			return $cData . $cSeparadorRegistros;
		}
		
		function getQuery( $cDelimitadorCampo = "'", $cSeparadorCampo = "," , $cSeparadorRegistros = "\n" ) 
		{
			// Si No hay un Query da Error
			if ( $this->nQuery )
			{
				return false;	
			}
			
			// Por cada Registro del Query arma una cadena con los valores separados por los delimitadores
			$cData = "";
			$nPosicion = 0;		
			while ( $this->moveTo($nPosicion) ) 
			{
				$cData .= $this->getFields( $cDelimitadorCampo, $cSeparadorCampo ) . $cSeparadorRegistros ;
				$nPosicion++;
			}
			// Devuelve la cadena
			return $cData;
		}
	
		/// Devuelve los Campos del Actual registro separados por Comas
		function getFields( $cDelimitadorCampo = "'", $cSeparadorCampo = "," ) 
		{
			// Si No hay un Query da Error
			if ( $this->nQuery )
			{
				return false;	
			}
			// Por cada Campo del Registro Actual, arma una cadena separada por los Delimitadores
			$cLinea = "";			
			$nqCampos = count($this->aFields) / 2;
			for( $nCampo = 0; $nCampo < $nqCampos; $nCampo++ ){
				$cField  = $this->aFields[$nCampo];
				$cLinea .=  $cDelimitadorCampo . $cField . $cDelimitadorCampo . $cSeparadorCampo;
			}
			if ( $cLinea != "" )
			{
				$cLinea = substr( $cLinea , 0, strlen($cLinea) - strlen($cSeparador) );
			}
			// Devuelve la cadena
			return $cLinea;
		}
	
		function status() 
		{
			return 'Server: ' . $this->cServer . ' Database: ' . $this->cDatabase . ' User: ' . $this->cUser . ' ' . ' ConId: ' . $this->nConnection ;
		}
	
		function connect( $bPersistente = false) 
		{
			if ( $bPersistente ) 
			{
				//$this->nConnection = mssql_pconnect( $this->cServer, $this->cUser, $this->cPassword );
				$this->nConnection = mssql_connect( $this->cServer, $this->cUser, $this->cPassword );
			} else 
			{
				$this->nConnection = mssql_connect( $this->cServer, $this->cUser, $this->cPassword );
			}
			
			// Si Hubo un Error
			if ( $this->nConnection == 0 ) 
			{
				addMessage("Error al intentar conectarse");
				return FALSE;
			}
			if ( !empty($this->cDatabase) ) 
			{
				if ( mssql_select_db ( $this->cDatabase , $this->nConnection ) != TRUE ) 
				{
					addMessage("Error al cambiar la Base de Datos");
					return FALSE;
				}
			}	
			return $this->nConnection;
		}
	
		function nextKey ( $cTabla, $cCampo, $cCondicion = '' ) {
			$nCodigo = 0;
			$this->cSql = "Select Max( $cCampo ) From $cTabla ";
	
			if ( $cCondicion != '' )
			{
				$this->cSql .=  ' Where ' . $cCondicion;
			}	
			$nCodigo = $this->getData ( $this->cSql );	
			return $nCodigo == NULL ? 1: ($nCodigo + 1);
		}	
		
		function getMatrix ( $cSql ) 
		{
			$nQuery = 0;
			$aReturn = array();
			$aRow = array();
			
			$this->cSql = $cSql;
			// Si no esta conectado => Intenta conectarse  y si da error => devuelve False
			if ( $this->nConnection == 0 && !$this->connect() )
			{
				return false;
			}
			$nQuery = mssql_query ($this->cSql, $this->nConnection);
			if ( $nQuery == TRUE ) 
			{
				while($aRow = mssql_fetch_array($nQuery )) 
				{
					$aReturn[] = $aRow;
				}
				mssql_free_result ( $nQuery );
			} else 
			{
				//addMessage($this->cSql);
			}
			return $aReturn;
		}
		
		function getKeyArray( $cSql ) 
		{
			$nQuery = 0;
			$aReturn = array();
			$aRow = array();
			
			$this->cSql = $cSql;
			// Si no esta conectado => Intenta conectarse  y si da error => devuelve False
			if ( $this->nConnection == 0 && !$this->connect() )
			{
				return false;
			}
			
			$nQuery = mssql_query ($this->cSql, $this->nConnection);
			
			if ( $nQuery == TRUE ) 
			{
				$aRow = mssql_fetch_row($nQuery );
				// Si es solo Codigo y Descripcion
				if ( count($aRow) == 2 ) 
				{
					if ( $aRow ) 
					{
						do 
						{
							$cIndex =  "" . $aRow[0];
							$aReturn[ $cIndex ] = $aRow[1];
							$aRow = mssql_fetch_row($nQuery );	
						} while ( $aRow );
					}
				} else 
				{
					// Si son Varios => Arma Array
					if ( $aRow ) 
					{
						do 
						{
							for ( $nRow = 0; $nRow < count($aRow) ; $nRow++ )
							{
								$aReturn[$aRow[0]][] = $aRow[$nRow];
							}	
							$aRow = mssql_fetch_row($nQuery );
						} while ( $aRow );
					}
				}
				mssql_free_result ( $nQuery );
			} else 
			{
				//addMessage($this->cSql);
			}	
			return $aReturn;
		}
		
		function getArray( $cSql ) 
		{
			$nQuery = 0;
			$aReturn = array();
			$aRow = array();
			
			$this->cSql = $cSql;
			// Si no esta conectado => Intenta conectarse  y si da error => devuelve False
			if ( $this->nConnection == 0 && !$this->connect() )
			{
				return false;
			}
			$nQuery = mssql_query ($this->cSql, $this->nConnection);
			if ( $nQuery == TRUE ) 
			{
				while($aRow = mssql_fetch_array($nQuery)) 
				{
					if ( count($aRow)  == 2) 
					{
						$aReturn = array_merge( (array)$aReturn, (array)$aRow[0] );
					} else
					{
						$aReturn = array_merge((array)$aReturn, (array)$aRow );
					}
				}
				mssql_free_result ( $nQuery );
			} else 
			{
				//addMessage($this->cSql);
			}	
			return $aReturn;
		}
		
		function getData( $cSql ) 
		{		
			$nQuery = 0;
			$cReturn = "";
			// Sin no esta conectado => Intenta conectarse  y si da error => devuelve False
			if ( $this->nConnection == 0 && !$this->connect() )
			{
				return false;
			}			
			$this->cSql = $cSql;
			$nQuery = mssql_query ($this->cSql, $this->nConnection);
			
			if ( $nQuery == TRUE ) 
			{ 
				if ( @mssql_num_rows( $nQuery ) > 0 ) 
				{
					$cReturn = mssql_result( $nQuery , 0, 0);			
					mssql_free_result ( $nQuery );    
				}
			} else 
			{
				//addMessage($this->cSql);
			}
			return $cReturn;
		}
	
		// Parametros $cTabla, { $cCampo, $cValor }
		function insertArray( $cTabla, $aCampos, $aValores ) 
		{
			$nContador = 0;	
			// Sin no esta conectado => Intenta conectarse  y si da error => devuelve False
			if ( $this->nConnection == 0 && !$this->connect() )
			{
				return false;
			}	
			$this->cSql = "INSERT INTO " . $cTabla . " ( ";	
			for ( $nContador = 0; $nContador < count($aCampos);  $nContador++  ) 
			{
				if ( $nContador != 0)
				{
					$this->cSql .= ", ";	
				}
				$this->cSql .= $aCampos[$nContador];
			}	
			$this->cSql .= ") VALUES ( ";	
			for ( $nContador = 0; $nContador < count($aValores);  $nContador++  ) 
			{
				if ( $nContador != 0)
				{
					$this->cSql .= ", ";
				}	
				$this->cSql .= $this->dbValue ( $aValores[$nContador] ) ;
			}
			$this->cSql .= ")";
			$bExito = ( mssql_query ($this->cSql, $this->nConnection) == FALSE ) ? false:  true;	
			if($bExito === false) 
			{
				//addMessage($this->cSql);
			}		
			return $bExito;
		}
	
		function insert( $cTabla, $cCampo, $cValor ) 
		{
			$nContador = 0;
			$bPrimero = true;
	
			// Sin no esta conectado => Intenta conectarse  y si da error => devuelve False
			if ( $this->nConnection == 0 && !$this->connect() )
			{
				return false;
			}	
			$this->cSql = "INSERT INTO " . $cTabla . " ( ";	
			for ( $nContador = 1; $nContador < func_num_args();  $nContador+=2  ) 
			{
				if ( $bPrimero )
				{
					$bPrimero = false;
				} else
				{
					$this->cSql .= ", ";
				}	
				$this->cSql .= func_get_arg($nContador);	
			}			
			$this->cSql .= ") VALUES ( ";	
			$bPrimero = true;
			for ( $nContador = 2; $nContador < func_num_args();  $nContador+=2  ) 
			{
				$cValor = $this->dbValue( func_get_arg($nContador) );
				if ( $bPrimero )
				{
					$bPrimero = false;
				} else {
					$this->cSql .= ", ";
				}	
				$this->cSql .= $cValor ;
			}	
			$this->cSql .= ")";
			$bExito = ( mssql_query ($this->cSql, $this->nConnection) == FALSE ) ? false:  true;					
			if($bExito === false) 
			{
				//addMessage($this->cSql);
			}		
			return $bExito;
		}
		
		/// Parametros $cTabla, { $cCampo, $cValor }, "Where", { $cClave, $cValor }
		function update ( $cTabla, $cCampo, $cValor, $Where, $cClave, $cValor ) 
		{
			$nContador = 0;
			$bPrimero = true;
			$cSeparador = ", ";	
			// Sin no esta conectado => Intenta conectarse  y si da error => devuelve False
			if ( $this->nConnection == 0 && !$this->connect() )
			{
				return false;
			}	
			$this->cSql = "UPDATE " . $cTabla . " SET ";	
			for ( $nContador = 1; $nContador < func_num_args();  $nContador+=2  ) 
			{
				if (!strcasecmp (func_get_arg($nContador), "WHERE") ) 
				{
					$this->cSql .= " WHERE " ;
					$nContador++;
					$cSeparador = " AND ";
					$bPrimero = true; // Vuelve a poner el flag del primero para saltear la primera ,
				}		
				$cValor = func_get_arg($nContador + 1);
				$cValor = $this->dbValue( func_get_arg($nContador + 1) );	
				if ( $bPrimero )
				{
					$bPrimero = false;
				} else
				{
					$this->cSql .= $cSeparador;	
				}
				$this->cSql .= func_get_arg($nContador) . " = " . $cValor;
			}			
			$bExito = ( mssql_query ($this->cSql, $this->nConnection) == FALSE ) ? false:  true;			
			if ($bExito === false) 
			{
				//addMessage($this->cSql);
			}	
			return $bExito;
		}
		
		// Parametros $cTabla, { $cClave, $cValor }
		function delete( $cTabla, $cClave, $cValor ) 
		{
			$nContador = 0;
			$cValor = "";
			$bPrimero = true;	
			// Sin no esta conectado => Intenta conectarse  y si da error => devuelve False
			if ( $this->nConnection == 0 && !$this->connect() )
			{
				return false;
			}	
			$this->cSql = "DELETE FROM  " . $cTabla . " WHERE ";	
			for ( $nContador = 1; $nContador < func_num_args();  $nContador+=2  ) 
			{
				$cValor = func_get_arg($nContador + 1);
				if ( substr(func_get_arg($nContador - 1), 0, 1) == "c" ) 
				{
					$cValor = "'" . $cValor . "'";
				}	
				if ( $bPrimero )
				{
					$bPrimero = false;
				} else
				{
					$this->cSql .= " AND ";
				}
				$this->cSql .= func_get_arg($nContador) . " = " . $cValor;
			}			
			$bExito = ( mssql_query ($this->cSql, $this->nConnection) == FALSE ) ? false:  true;
			if($bExito === false) 
			{
				//addMessage($this->cSql);
			}	
			return $bExito;	
		}
		//
		function query( $cSql, $nFrom = '', $nLenght = '' )
		{
			if ( $nFrom && $nLenght )
			{
				$nPos = strpos( $cSql, 'SELECT ');
				if ( $nPos )
				{
					$cSql = "SELECT TOP $nFrom " . substr( $cSql, $nPos + 7);
				}
			}		
			// Sino no esta conectado => Intenta conectarse  y si da error => devuelve False
			if ( $this->nConnection == false && !$this->connect() )
			{
				return false;
			}
			if ( $this->nQuery ) 
			{
				mssql_free_result ( $this->nQuery );
			}
			$this->cSql = $cSql;
			$this->nQuery = mssql_query ($this->cSql, $this->nConnection);			
			// Si hubo un Error
			if ( $this->nQuery === FALSE ) 
			{
				//addMessage($this->cSql);
			}
			return $this->nQuery;
		}
		// Devuelve: El Error que Recibe del Sql
		// Nota: Los Store Procedures deben devolver un String con el Error
		function execute ( $cSql) 
		{		
			// Sin no esta conectado => Intenta conectarse  y si da error => devuelve False
			if ( $this->nConnection == 0 && !$this->connect() )
			{
				return false;
			}
			$this->cSql = $cSql;
			$nQuery = mssql_query ($this->cSql, $this->nConnection);			
			if ($nQuery === false) 
			{
				//addMessage($this->cSql);
				$cRetorno = 'No se pudo ejecutar el Procedimiento en la Base de Datos ' . $this->cSql;
			} else 
			{
				if ( @mssql_num_rows( $nQuery ) > 0 ) 
				{
					$nRetorno = mssql_result( $nQuery , 0, 0);			
					list( $cRetorno, $nTipoError, $nTipoUsuario  ) =  mssql_fetch_array ( $nQuery );	
					if ( $cRetorno != '') 
					{
						addMessage( $cRetorno ); // $nTipoError
					}
					mssql_free_result ( $nQuery );
				}        	
			}
			return $cRetorno;
		}
		//
		function count() 
		{
			if ( $this->nQuery == FALSE )
			{
				return false;
			}
			return mssql_num_rows ( $this->nQuery );
		}
		//		
		function moveTo( $nRow = -1) 
		{
			if ( $this->nQuery == 0 )
			{
				return false;
			}
			if ( $nRow <= -1 ) 
			{
				return $this->moveNext();
			}
			if ( $nRow >= mssql_num_rows ( $this->nQuery ) )
			{
				return false;
			}
			
			if ( ! mssql_data_seek ( $this->nQuery, $nRow ) ) 
			{
				return false;
			}
			$this->aFields = mssql_fetch_array ( $this->nQuery ) ;		
			return !empty($this->aFields);
		}
	
		function __goTo( $nRow = -1) 
		{
			if ( $this->nQuery == 0 )
			{
				return false;
			}
			if ( $nRow < 0 ) 
			{
				$nRow = 0;
			}
			if ( $nRow >= mssql_num_rows ( $this->nQuery ) ) 
			{
				return false;
			}
			if ( ! mssql_data_seek ( $this->nQuery, $nRow ) ) 
			{
				return false;
			}		
			return true;
		}
		
		function moveNext( $bAsociativo = 1 ) 
		{	
			if ( $this->nQuery == 0 )
			{
				return false;
			}
			if ( $bAsociativo == 1 ) 
			{
				$this->aFields = mssql_fetch_array ( $this->nQuery ) ;
			} else {
				$this->aFields = mssql_fetch_row ( $this->nQuery ) ;		
			}
			$this->bEof = !empty($this->aFields);
			
			return $this->bEof;
		}	
		
		// Funcion Insert con Minima Carga para subir grandes Volumenes
		// Parametros $cSql
		function executeDirect( $cSql ) 
		{	
			$this->cSql = $cSql ;			
			$bExito = ( mssql_query ($this->cSql, $this->nConnection) == FALSE ) ? false:  true; 
			if ( $bExito == false) 
			{
				//addMessage($this->cSql);
			}
			return $bExito;
		}
	}
?>
